/**
 * @file STL_Tools.h
 * @author Derek Liu (yjkhtddx@sina.com)
 * @brief 
 * @version 0.1
 * @date 2020-09-10
 * 
 * @copyright Copyright Sci-Tech Laboratories (c) 2020
 * 
 */

#ifndef __STL_TOOLS_H__
#define __STL_TOOLS_H__

#include <unistd.h> //close

#include "STLOG.h"
#include "STL_SYNTHESIZE.h"

// 部分编译器不支持这种写法
// #ifdef __cplusplus
// #define STL_BEGIN \
//     namespace STL \
//     {
// #define STL_END }
// #define USING_NS_STL using namespace STL
// #define NS_STL ::STL
// #else
// #define STL_BEGIN
// #define STL_END
// #define USING_NS_STL
// #define NS_STL
// #endif

#define STL_SAFE_DELETE(p) \
    do                     \
    {                      \
        if (p)             \
        {                  \
            delete (p);    \
            (p) = nullptr; \
        }                  \
    } while (0)

#define STL_SAFE_CLOSE(fd) \
    do                     \
    {                      \
        if (fd > 0)        \
        {                  \
            close(fd);     \
            fd = -1;       \
        }                  \
    } while (0)

#define STL_SAFE_DELETE_ARRAY(p) \
    do                           \
    {                            \
        if (p)                   \
        {                        \
            delete[](p);         \
            (p) = nullptr;       \
        }                        \
    } while (0)
#define STL_SAFE_FREE(p)   \
    do                     \
    {                      \
        if (p)             \
        {                  \
            free(p);       \
            (p) = nullptr; \
        }                  \
    } while (0)
#define STL_BREAK_IF(cond) \
    if (cond)              \
    break

// 无参数调用（可预设多个参数）
#define STL_CALLBACK_0(__selector__, __target__, ...) std::bind(&__selector__, __target__, ##__VA_ARGS__)
// 一个参数调用（可预设多个参数）
#define STL_CALLBACK_1(__selector__, __target__, ...) std::bind(&__selector__, __target__, std::placeholders::_1, ##__VA_ARGS__)
// 两个参数调用（可预设多个参数）
#define STL_CALLBACK_2(__selector__, __target__, ...) std::bind(&__selector__, __target__, std::placeholders::_1, std::placeholders::_2, ##__VA_ARGS__)
// 三个参数调用（可预设多个参数）
#define STL_CALLBACK_3(__selector__, __target__, ...) std::bind(&__selector__, __target__, std::placeholders::_1, std::placeholders::_2, std::placeholders::_3, ##__VA_ARGS__)

namespace STL
{
    typedef unsigned char uint8;
    typedef unsigned short uint16;
    typedef unsigned int uint32;
    typedef unsigned long uint64;
} // namespace STL

#endif /* __STL_TOOLS_H__ */